<template>
  <view class="progress-container">
    <slot name="first"></slot>
    <view id="outline" class="outline" @click="handleTouchClick">
      <view
        id="button"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
        :style="{
          left: pageStyleModule.buttonLeft,
          height: buttonSize,
          width: buttonSize
        }"
        class="button">
      </view>
      <view
        class="inline"
        :style="{ width: pageStyleModule.lineWidth }">
      </view>
    </view>
    <slot name="last"></slot>
  </view>
</template>

<script setup lang="ts">
  import {
    defineProps,
    defineEmits,
    onMounted,
    getCurrentInstance,
    reactive,
    watch,
  } from "vue";

  let query: UniApp.SelectorQuery | null = null;

  const props = defineProps({
    max: {
      type: [Number],
      default: 0
    },
    current: {
      type: [Number],
      default: 0
    },
    outsideColor: {
      type: [String],
      default: '#F9EEDC'
    },
    insideColor: {
      type: [String],
      default: '#FFD388'
    },
    buttonSize: {
      type: [String],
      default: '1.6rem'
    }
  });

  const pageModule = reactive({
    contentWidth: 0,
    contentLeft: 0,
    buttonWidth: 0
  });

  const pageStyleModule = reactive({
    buttonLeft: '-0.8rem',
    lineWidth: '0'
  });

  const emit = defineEmits(['onTouchMove', 'onTouchClick', 'onTouchEnd']);

  onMounted(() => {
    query = uni.createSelectorQuery().in(getCurrentInstance());
    query.selectAll('#outline, #button').boundingClientRect(([outline, button]: any) => {
      pageModule.contentWidth = outline.width;
      pageModule.contentLeft = outline.left;
      pageModule.buttonWidth = button.width;
    }).exec(() => {
      setProgressStyle(props.current);
    });
  });

  watch(() => props.current, (newValue) => setProgressStyle(newValue));

  const setProgressStyle = (newValue: number) => {
    let left = pageModule.contentWidth / props.max * newValue;
    pageStyleModule.buttonLeft = left - pageModule.buttonWidth / 2 + 'px';
    pageStyleModule.lineWidth = left + 'px';
  }

  const getOffsetCurrent = (clientX: any) => {
    let current = (clientX - pageModule.contentLeft) / (pageModule.contentWidth / props.max);
    if (current >= props.max) {
      current = props.max;
    }
    if (current <= 0) {
      current = 0;
    }
    return current;
  }

  const handleTouchClick = ({ changedTouches: [hand] }: any) => {
    const current = getOffsetCurrent(hand.clientX);
    emit('onTouchClick', current);
  }

  const handleTouchMove = ({ changedTouches: [hand] }: any) => {
    const current = getOffsetCurrent(hand.clientX);
    emit('onTouchMove', current);
  }

  const handleTouchEnd = ({ changedTouches: [hand] }: any) => {
    const current = getOffsetCurrent(hand.clientX);
    emit('onTouchEnd', current);
  }
</script>

<style scoped lang="scss">
  .progress-container {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .outline {
      flex: 1;
      margin-left: 1.2rem;
      margin-right: 1.2rem;
      height: 0.4rem;
      border-radius: 0.5rem;
      background-color: #F9EEDC;
      position: relative;

      .inline {
        height: 100%;
        border-radius: 0.5rem;
        background-color: #FFD388;
        position: absolute;
        top: 0;
        left: 0;
      }

      .button {
        position: absolute;
        border: 1px solid #A87F71;
        background-color: #fff;
        border-radius: 50%;
        z-index: 1;
        left: -0.8rem;
        top: 50%;
        transform: translateY(-50%);
        box-sizing: border-box;
      }
    }
  }
</style>